Google Calendar Busy Check
A small Python script that reports your current availability from Google Calendar, using uv inline dependencies.
It outputs:
Busy until HH:MM— you are currently in a meeting that counts as busy.Free until HH:MM— you are not busy, and the next busy meeting starts at that time.Free— no busy meetings ahead in the look-ahead window.
Then it logs a list of all remaining events for today, marking each as BUSY or FREE according to the same rules.
Requirements
- Python 3.12+
- uv
- A Google account with access to the calendar you want to read
Setup
-
Clone / download this gist
git clone https://gist.github.com/<your-gist-id>.git cd <gist-dir> -
Enable the Google Calendar API
-
Open Google Cloud Console.
-
Create (or select) a project.
-
Enable Google Calendar API.
-
Create OAuth 2.0 Client ID credentials → Desktop App.
-
Download the credentials JSON and save it in this directory as:
credentials.json
-
-
First run (auth flow)
uv run check_busy.py- A browser window opens to authorize access.
- After approval, the script writes
token.jsonlocally. - Subsequent runs reuse
token.jsonand won’t prompt again.
Usage
Run from the terminal:
uv run check_busy.py
Example output:
Busy until 14:30
Today's remaining events:
- 14:00–14:30 [BUSY] Client sync
- 15:00–15:30 [FREE] Focus time
- 16:00–17:00 [BUSY] Project planning
Busy / Free Rules
An event is considered BUSY if:
-
It has a specific time window (not all-day), and
-
It is time-blocking (not
transparent), and -
It is not:
- a Focus Time block (
"focus"in title), - an Out-of-Office block (
"ooo"in title), - an
outOfOfficeevent type, - or a meeting you have declined.
- a Focus Time block (
Declined meetings are treated as if they don’t exist:
- they do not make you busy,
- they do not show up in the “Today’s remaining events” log.
All-day events are treated as FREE (all-day) and don’t affect busy/free state.
What the Script Does
-
Reads your primary calendar.
-
Looks ahead ~4 hours to decide:
- whether you’re in a busy event now,
- or when the next busy event starts.
-
Lists all remaining events today and tags each BUSY/FREE.
You can tweak horizons and logic in:
get_current_and_next_event()(look-ahead window)is_event_busy()(classification rules)
Security Notes
- OAuth tokens are stored locally in
token.json. - Scope is read-only:
calendar.readonly. - Revoke access at Google Account → Security → Third-party access.
Reset / Cleanup
To force re-authorization:
rm token.json
uv run check_busy.py